if (NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_MACCATALYST)
  set(FEATURE_TIERED_COMPILATION 1)
  set(FEATURE_REJIT 1)
  set(FEATURE_JIT 1)
endif()

if (CLR_CMAKE_TARGET_ARCH_WASM OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST)
  set(FEATURE_STATICALLY_LINKED 1)
endif()

if(CLR_CMAKE_TARGET_TIZEN_LINUX)
  set(FEATURE_GDBJIT_LANGID_CS 1)
endif()

if(NOT DEFINED FEATURE_EVENT_TRACE)
  if (NOT CLR_CMAKE_TARGET_BROWSER)
    # To actually disable FEATURE_EVENT_TRACE, also change clr.featuredefines.props
    set(FEATURE_EVENT_TRACE 1)
  endif()
endif(NOT DEFINED FEATURE_EVENT_TRACE)

if(NOT DEFINED FEATURE_EVENTSOURCE_XPLAT)
  if (CLR_CMAKE_TARGET_LINUX AND NOT CLR_CMAKE_TARGET_ANDROID)
    # To actually disable FEATURE_EVENTSOURCE_XPLAT, also change clr.featuredefines.props
    set(FEATURE_EVENTSOURCE_XPLAT 1)
  endif()
endif(NOT DEFINED FEATURE_EVENTSOURCE_XPLAT)

if(NOT DEFINED FEATURE_PERFTRACING AND FEATURE_EVENT_TRACE)
  set(FEATURE_PERFTRACING 1)
endif(NOT DEFINED FEATURE_PERFTRACING AND FEATURE_EVENT_TRACE)

if(NOT DEFINED FEATURE_DBGIPC)
  if(CLR_CMAKE_TARGET_UNIX)
    set(FEATURE_DBGIPC 1)
  endif()
endif(NOT DEFINED FEATURE_DBGIPC)

if(NOT DEFINED FEATURE_INTERPRETER)
  if(CLR_CMAKE_TARGET_ANDROID)
    set(FEATURE_INTERPRETER 0)
  elseif(CLR_CMAKE_TARGET_ARCH_WASM)
    set(FEATURE_INTERPRETER 1)
    set(FEATURE_PORTABLE_ENTRYPOINTS 1)
    set(FEATURE_PORTABLE_HELPERS 1)
  elseif(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST)
    set(FEATURE_INTERPRETER 1)
  else()
    if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
      set(FEATURE_INTERPRETER $<IF:$<CONFIG:Debug,Checked>,1,0>)
    else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
      set(FEATURE_INTERPRETER 0)
    endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
  endif()
endif(NOT DEFINED FEATURE_INTERPRETER)

if(NOT DEFINED FEATURE_STANDALONE_GC)
  set(FEATURE_STANDALONE_GC 1)
endif(NOT DEFINED FEATURE_STANDALONE_GC)

if(NOT DEFINED FEATURE_AUTO_TRACE)
  set(FEATURE_AUTO_TRACE 0)
endif(NOT DEFINED FEATURE_AUTO_TRACE)

if(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS)
  set(FEATURE_SINGLE_FILE_DIAGNOSTICS 1)
endif(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS)

if ((CLR_CMAKE_TARGET_WIN32 OR CLR_CMAKE_TARGET_UNIX) AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
  set(FEATURE_COMWRAPPERS 1)
endif()

if (CLR_CMAKE_TARGET_APPLE)
  set(FEATURE_OBJCMARSHAL 1)
endif()

if(NOT DEFINED FEATURE_JAVAMARSHAL)
  if(CLR_CMAKE_TARGET_ANDROID)
    set(FEATURE_JAVAMARSHAL 1)
  else()
    set(FEATURE_JAVAMARSHAL $<IF:$<CONFIG:Debug,Checked>,1,0>)
  endif()
endif()

if (CLR_CMAKE_TARGET_WIN32)
  set(FEATURE_TYPEEQUIVALENCE 1)
endif(CLR_CMAKE_TARGET_WIN32)

if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS)
  set(FEATURE_STUBPRECODE_DYNAMIC_HELPERS 1)
endif()

if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_ARCH_WASM)
  set(FEATURE_CORECLR_CACHED_INTERFACE_DISPATCH 1)
  set(FEATURE_CORECLR_VIRTUAL_STUB_DISPATCH 0)
else()
  # Enable cached interface dispatch so that we can test/debug it more easily on non-embedded scenarios (set DOTNET_UseCachedInterfaceDispatch=1)
  # Only enable in chk/debug builds as this support isn't intended for retail use elsewhere
  if (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
    set(FEATURE_CORECLR_CACHED_INTERFACE_DISPATCH $<IF:$<CONFIG:Debug,Checked>,1,0>)
  else()
    set(FEATURE_CORECLR_CACHED_INTERFACE_DISPATCH 0)
  endif()
  set(FEATURE_CORECLR_VIRTUAL_STUB_DISPATCH 1)
endif()

# We use a flush instruction cache to protect reads from the StubPrecodeData/CallCountingStub structures in the stubs.
# This is needed because the StubPrecodeData structure is initialized after the stub code is written, and we need to ensure that
# the reads in the stub happen after the writes to the StubPrecodeData structure. We could do this with a barrier instruction in the stub,
# but that would be more expensive.
set(FEATURE_CORECLR_FLUSH_INSTRUCTION_CACHE_TO_PROTECT_STUB_READS 1)

if (CLR_CMAKE_HOST_UNIX AND CLR_CMAKE_HOST_ARCH_AMD64)
  # Allow 16 byte compare-exchange (cmpxchg16b)
  add_compile_options($<${FEATURE_CORECLR_CACHED_INTERFACE_DISPATCH}:-mcx16>)
endif()
